package com.waves.task.strategy.task;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.waves.core.constant.DigitConstant;
import com.waves.core.constant.redis.UserRedisKey;
import com.waves.core.utils.LoginUtils;
import com.waves.core.utils.RedisUtils;
import com.waves.task.domain.dto.TaskPageDTO;
import com.waves.task.domain.enums.TaskTypeEnum;
import com.waves.task.domain.vo.TaskVO;
import org.springframework.data.geo.GeoResults;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 附近人帖策略类
 */
@Component
public class TaskNearStrategy extends AbstractTaskStrategy {
    @Override
    TaskTypeEnum getTaskTypeEnum() {
        return TaskTypeEnum.TASK_TYPE_NEAR;
    }

    @Override
    public TaskPageDTO dealTaskPageDTO(TaskPageDTO dto) {
        List<Long> userIds = new ArrayList<>();
        String myUid = LoginUtils.getUserId().toString();
        // 经纬度不为空 查询附近帖子信息
        if (dto.getX() != null) {
            String key = UserRedisKey.USER_INFO_GEO;
            // 以当前坐标为圆心，距离为半径，查询符合条件的人
            Point myPoint = new Point(dto.getX(), dto.getY());
            GeoResults<RedisGeoCommands.GeoLocation<Object>> search = RedisUtils.gGet(key, myPoint,dto.getDistance());
            assert search != null;
            Map<Long, String> distanceMap = new HashMap<>();
            // 由于通过radius方法获取距离单位是NEUTRAL 且无法设置返回KILOMETERS，所以1转换NEUTRAL、2重新获取距离，采用策略2
            if (CollUtil.isNotEmpty(search.getContent())) {
                search.getContent().forEach(result -> {
                    // redis的geo中存的是uid
                    Long uid = Long.parseLong(result.getContent().getName().toString());
                    userIds.add(uid);
                    // 查询两者距离
                    Point otherPoint = result.getContent().getPoint();
                    String distance = RedisUtils.getGeoDistance(key, myPoint, otherPoint,myUid, uid.toString());
                    distanceMap.put(uid, distance);
                    dto.setDistanceMap(distanceMap);
                });
            } else {
                // 没有查询到符合条件的 自动设置一个找不到的数据
                userIds.add(DigitConstant.DIGIT_UID);
            }
            dto.setUserIds(userIds);
        }
        return dto;
    }

    @Override
    public IPage<TaskVO> getTaskVOPage(TaskPageDTO dto) {
        return super.searchAndDealPage(dealTaskPageDTO(dto));
    }


}
